In [1]:
# https://people.duke.edu/~ccc14/sta-663/PyMC2.html
In [33]:
dose = np.asarray([-0.896, -0.296, -0.053, 0.727])
rats = np.asarray([5,5,5,5])
deaths = np.asarray([0,1,3,5])
In [31]:
import pymc
from pprint import pprint
import numpy as np
import matplotlib.pyplot as plt
import spacepy.plot as spp
We will model the number of deaths as a random sample from a binomial distribution, where $n$ is the number of rats and $p$ the probabbility of a rat dying. We are given $n=5$, but we believve that $p$ may be related to the drug dose $x$. As $x$ increases the number of rats dying seems to increase, and since $p$ is a probability, we use the following model:
$ y \sim Bin(n,p) \\ logit(p) = \alpha + \beta x \\ a \sim N(0,5) \\ \beta \sim N(0,10) $
where we set vague priors for αα and ββ, the parameters for the logistic model.
In [15]:
# define invlogit function
def invlogit(x):
return pymc.exp(x) / (1 + pymc.exp(x))
In [22]:
# observed data
dose, rats, deaths
# define priors
alpha = pymc.Normal('alpha', mu=0, tau=1.0/5**2)
beta = pymc.Normal('beta', mu=0, tau=1.0/10**2)
# define likelihood
p = pymc.InvLogit('p', alpha + beta*dose)
y = pymc.Binomial('y_obs', n=rats, p=p, value=deaths, observed=True)
# inference
m = pymc.Model([alpha, beta, y])
mc = pymc.MCMC(m)
mc.sample(iter=21000, burn=1000, burn_till_tuned=True, thin=20)
In [23]:
pymc.Matplot.plot(mc)
In [24]:
pprint(mc.stats())
In [38]:
xp = np.linspace(-1, 1, 100)
a = alpha.stats()['mean']
b = beta.stats()['mean']
plt.plot(xp, invlogit(a + b*xp).value)
plt.scatter(dose, deaths/5, s=50);
plt.xlabel('Log dose of drug')
plt.ylabel('Risk of death')
Out[38]:
In [56]:
# one should be able to get estimates of the line uncertainity
ilu = np.empty((1000, len(xp)), dtype=float)
for ii, v in enumerate(np.random.random_integers(0, len(alpha.trace[:])-1, 1000)):
ilu[ii] = invlogit(alpha.trace[:][v] + beta.trace[:][v]*xp).value
In [57]:
ilu
Out[57]:
In [64]:
xp = np.linspace(-1, 1, 100)
for v in ilu:
plt.plot(xp, v, alpha=.01, c='r')
a = alpha.stats()['mean']
b = beta.stats()['mean']
plt.plot(xp, invlogit(a + b*xp).value)
a = alpha.stats()['quantiles'][50]
b = beta.stats()['quantiles'][50]
plt.plot(xp, invlogit(a + b*xp).value, c='y')
plt.scatter(dose, deaths/5, s=50);
plt.xlabel('Log dose of drug')
plt.ylabel('Risk of death')
Out[64]:
In [63]:
alpha.stats()
Out[63]:
In [ ]: